package com.ssm.reactive.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * 安全配置
 */
@Configuration(proxyBeanMethods = false)
public class WebSecurityConfig {
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    SecurityWebFilterChain httpAuthorization(ServerHttpSecurity httpSecurity) { // Http 授权
        return httpSecurity
                .cors(withDefaults())
                .httpBasic(withDefaults())
                .csrf(ServerHttpSecurity.CsrfSpec::disable)
                .authorizeExchange(auth -> auth
                        .pathMatchers("/employees").authenticated()
                        .anyExchange().permitAll()
                ).build();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() { // 跨域
        CorsConfiguration configuration = new CorsConfiguration();
        // config.applyPermitDefaultValues() // Possibly...
        configuration.setAllowCredentials(true);
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    ReactiveUserDetailsService authentication() { // 用户认证 Authentication
        return new MapReactiveUserDetailsService(User.withDefaultPasswordEncoder()
                .username("jlong").password("pw").roles("admin").build()
        );
    }
}
